#pragma once
#include <QString>
#include <QIcon>  //图标类
#include <QTime>
#include <QFile>
#include <QFileInfo>
#include <QUuid>
namespace model
{

// 添加一些工具函数方便后续复用
static inline QString getFileName(const QString& path) {
    QFileInfo fileInfo(path);  //要独自包含<QFileInfo>头文件
    return fileInfo.fileName();
}

//两种日志打印方式
// 1.封装一个 "宏" 作为打印日志的方式. __FILE__,__LINE__是C++中的宏分别表示当前文件，和当前所在行
#define TAG QString("[%1:%2]").arg(model::getFileName(__FILE__), QString::number(__LINE__))
// 2.#define TAG "[" << __LINE__ << "]"

// qDebug 打印字符串的时候, 就会自动加上 " "，使用noquote()就能去除 " "。
#define LOG() qDebug().noquote() << TAG

// 要求函数的定义如果写在 .h 中, 必须加 static 或者 inline (当然两个都加也可以), 避免链接阶段出现 "函数重定义" 的问题.
static inline QString formatTime(int64_t timestamp) {
    // 先把时间戳, 转换成 QDateTime 对象
    QDateTime dateTime = QDateTime::fromSecsSinceEpoch(timestamp);
    // 把 QDateTime 对象转成 "格式化时间"
    return dateTime.toString("MM-dd HH:mm:ss");
}

// 通过这个函数得到 秒级 的时间
static inline int64_t getTime() {
    return QDateTime::currentSecsSinceEpoch();
}

// 根据 QByteArray, 转成 QIcon
static inline QIcon makeIcon(const QByteArray& byteArray) {
    QPixmap pixmap;
    pixmap.loadFromData(byteArray);//使用指定的格式和转换标志从二进制数据加载一个像素图。
    QIcon icon(pixmap);
    return icon;
}

// 读写文件操作.
// 从指定文件中, 读取所有的二进制内容. 得到一个 QByteArray
static inline QByteArray loadFileToByteArray(const QString& path) {
    QFile file(path);
    bool ok = file.open(QFile::ReadOnly);
    if (!ok) {
        LOG() << "文件打开失败!";
        return QByteArray();
    }
    QByteArray content = file.readAll();
    file.close();
    return content;
}

// 把 QByteArray 中的内容, 写入到某个指定文件里
static inline void writeByteArrayToFile(const QString& path, const QByteArray& content) {
    QFile file(path);
    bool ok = file.open(QFile::WriteOnly);
    if (!ok) {
        LOG() << "文件打开失败!";
        return;
    }
    file.write(content);
    file.flush();
    file.close();
}

// 工具函数end

//用户信息类
class UserInfo
{
public:
    QString userId;        //用户编号
    QString userName;      //用户名字
    QString userHeads;     //用户头像
    QString userSignature; //用户签名
    QString userPhone;     //用户名字

};

//消息类型枚举
enum MessageType
{
    TEXT_TYPE,               //文本消息
    PICTURE_TYPE,           //图片
    FILE_TYPE,              //文件
    VOICE_TYPE              //语音
};

//信息类
class Message
{
public:
    QString messageId;      //消息id
    QString chatSessionId;  //会话id
    QString lastTime;       //最后时间
    MessageType messageType;//消息类型
    UserInfo sender;        //消息发送者
    QByteArray content;     //存储消息
    QString filed;          //文件
    QString fileName;       //文件名


public:
    // 此处 extraInfo 目前只是在消息类型为文件消息时, 作为 "文件名" 补充.
    static Message makeMessage(MessageType messageType, const QString& chatSessionId, const UserInfo& sender,
                               const QByteArray& content, const QString& extraInfo) {
        if (messageType == TEXT_TYPE) {
            return makeTextMessage(chatSessionId, sender, content);
        } else if (messageType == PICTURE_TYPE) {
            return makeImageMessage(chatSessionId, sender, content);
        } else if (messageType == FILE_TYPE) {
            return makeFileMessage(chatSessionId, sender, content, extraInfo);
        } else if (messageType == VOICE_TYPE) {
            return makeVoiceMessage(chatSessionId, sender, content);
        } else {
            // 触发了未知的消息类型
            return Message();
        }
    }
    static QString makeId() {
        return "M" + QUuid::createUuid().toString();
    }
private:
    //通过Uuid获取唯一值
    // static QString makeId() {
    //     return "M" + QUuid::createUuid().toString().sliced(25,12);
    // }
    static Message makeTextMessage(const QString& chatSessionId, const UserInfo& sender,const QByteArray& content)
    {
        Message message;
        message.messageId = ""; //确保Id是唯一的 可以通过uuid 和雪花算法 获取全世界唯一的值。
        message.chatSessionId = chatSessionId;
        message.messageType = TEXT_TYPE;
        message.sender = sender;
        message.content = content;
        message.filed="";
        message.fileName="";

        return message;
    }
    static Message makeImageMessage(const QString& chatSessionId, const UserInfo& sender,const QByteArray& content)
    {
        Message message;
        message.messageId = ""; //确保Id是唯一的 可以通过uuid 和雪花算法 获取全世界唯一的值。
        message.chatSessionId = chatSessionId;
        message.messageType = PICTURE_TYPE;
        message.sender = sender;
        message.content = content;
        message.filed="";
        message.fileName="";

        return message;
    }
    static Message makeFileMessage(const QString& chatSessionId, const UserInfo& sender,const QByteArray& content,const QString& fileName)
    {
        Message message;
        message.messageId = ""; //确保Id是唯一的 可以通过uuid 和雪花算法 获取全世界唯一的值。
        message.chatSessionId = chatSessionId;
        message.messageType = FILE_TYPE;
        message.sender = sender;
        message.content = content;
        message.filed="";
        message.fileName=fileName;

        return message;
    }
    static Message makeVoiceMessage(const QString& chatSessionId, const UserInfo& sender,const QByteArray& content)
    {
        Message message;
        message.messageId = ""; //确保Id是唯一的 可以通过uuid 和雪花算法 获取全世界唯一的值。
        message.chatSessionId = chatSessionId;
        message.messageType = VOICE_TYPE;
        message.sender = sender;
        message.content = content;
        message.filed="";
        message.fileName="";

        return message;
    }

};

//会话信息类
class ChatSessionInfo
{
public:
    QString chatSessionId;      //会话id
    QString chatSessionNAME;    //会话名，私聊：对方名字/群聊：群聊名字
    Message lastMessage;        //最新的消息
    QIcon  userHeads;           //用户头像
    QString userId;             //用户id
};

} //end model
